'''
Created on 18/03/2009

@author: eh01
'''
from yarra.datastore.dsstub import DSStub
from yarra.event.event import Event
from yarra.event.eventdispatcher import EventDispatcher
from yarra.event.eventqueue import EventQueue


class EventManager(object):
    '''
    classdocs
    '''
    __eventQueue = None
    __eventDispatchers = None
    __number_of_dispatchers = None
    
    def __init__(self):
        '''
        Constructor
        '''        
        # constructor runs each time __new__ returns a instance, so we
        # have a check to make sure we don't initialize again. YES its weird
        # that even though the same instance is returned, it still runs
        # this __init__ method
        ds_stub = DSStub()
        self.__number_of_dispatchers = ds_stub.get_number_of_event_dispatchers()
        if self.__eventQueue is None and self.__eventDispatchers is None:
            self.__eventQueue = EventQueue()     
            self.__eventDispatchers = []
            for i in range(self.__number_of_dispatchers):
                self.__eventDispatchers.append(EventDispatcher(self.__eventQueue, self.get_eventHandlers()))        

    def __new__(cls, *args, **kwargs): 
        if not hasattr(cls, 'self'):
            cls.self = object.__new__(cls, *args, **kwargs)
        return cls.self    

    def start(self):        
        for eventDispatcher in self.__eventDispatchers:
            eventDispatcher.start()
        return True
    
    def stop(self):
        for i in range(self.__number_of_dispatchers):
            self.__eventQueue.put(Event('STOP', 'STOPPING'))
        
        while self.is_at_least_one_dispatcher_alive():
            pass
        print 'Dispatchers shutdown'
        
        return True
    
    def add_event(self, event):
        self.__eventQueue.put(event)
        
    def has_events(self):
        return not self.__eventQueue.empty()
    
    def get_eventHandlers(self):
        # This eventually will read from the datastore
        # For testing and demo purposes, just override this method
        return None
    
    def is_at_least_one_dispatcher_alive(self):
        for eventDispatcher in self.__eventDispatchers:
            if eventDispatcher.isAlive():
                return True
        return False      